export function stringify(obj: any): string {
  const result = parsing(obj)

  return result
}

function parsing(val: any) {
  // 获取类型名称
  const typeStr = getTypeStr(val)
  // 获取相应的解析函数
  const parser = getTypeParser(typeStr)
  // 返回字符串结果
  const result = parser(val)

  return result
}

/**
 * 存放解析函数的对象
 */
const typeParsers: Record<string, (a: any) => string> = {
  number: numParser,
  string: strParser,
  boolean: boolParser,
  array: arrayParser,
  object: objectParser
}

/**
 * 
 * @param v 变量类型
 * @returns 类型名称
 */
function getTypeStr(v: any) {
  if (Array.isArray(v)) return "array"

  const varType = typeof v

  return varType
}

/**
 * 根据类型名称, 获取解析函数
 * @param typeName 
 * @returns 
 */
function getTypeParser(typeName: string): (a: any) => string {
  const parser = typeParsers[typeName]

  // undefined 或 null等 的情况
  if (parser === undefined) {
    return defaultParser
  } else {
    return parser
  }
}

function numParser(val: number) {
  return val.toString()
}

function strParser(val: string) {
  return `\"${val}\"`
}

function boolParser(val: boolean) {
  return val ? "true" : "false"
}

function arrayParser(val: Array<any>) {
  // 空数组情况
  if (val.length === 0) {
    return "[]"
  }

  let result = "["

  // 遍历去获取对应的解析, 解析成字符串
  let index = 0
  do {
    const itemResult = parsing(val[index])
    result += itemResult

    // 除了最后一个元素外, 每次解析完都要加上逗号
    if (index < val.length - 1) {
      result += ","
    }
    index++
  } while (index < val.length)

  result += "]"

  return result
}

/**
 * 
 * @param val 
 * @returns 
 */
function objectParser<T extends object>(val: T) {
  let result = "{"

  const keys = Object.keys(val)

  // 获取对象的键名称
  type keyType = keyof T

  keys.forEach((key, index) => {
    const keyResult = strParser(key)
    result += keyResult

    result += ":"

    const valueResult = parsing(val[key as keyType])
    result += valueResult

    if (index < keys.length - 1) {
      result += ","
    }
  })

  result += "}"

  return result
}

function defaultParser(val: any) {
  return ""
}